package control
{
   	import flash.display.MovieClip;
   	import flash.events.MouseEvent;
   	import flash.geom.Point;
   	import flash.ui.Mouse;
   	import flash.utils.clearInterval;
   	import flash.utils.getTimer;
   	import flash.utils.setInterval;
	
   	public class ScaleBoundMarker extends MovieClip
   	{
      	private const _UPDATE_POSITION_INTER: Number = 10; //ms

      	private const _DBLCLICK_INTER: Number = 100; // ms
      
      	private var dblclickInter: uint;

      	private var dblclick: Boolean = false;

     	private var lastUpdateTime: Number = 0.0;

      	private var isDrag: Boolean = new Boolean;

      	public var horizontalDrag: Boolean = true;

      	public var verticalDrag: Boolean = true;

      	public var saveProportins: Boolean = false;

		/**
		 * Scale marker type. ScaleMarkerType.
		 */
      	public var type: String;
      
		/**
		 *	Cursor displays when user over mouse pointer on this marker 
		 */
      	public var cursor: MovieClip = null;
		
      	/** 
		 * Constructor 
		 * @param type String
		 * @param cursor MovieClip
		 */
      	public function ScaleBoundMarker(type:String=ScaleMarkerType.LEFT_TOP, cursor:MovieClip=null) 
		{
         	super();
         	this.type = type;
			if (cursor != null)
				this.cursor = cursor;
			else
				this.cursor = cursor;//MovieClip(new ScaleCursor());
			
         	this.cursor.name = "cursor";
         	drawUp();
         	
         	addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
         	addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
         	addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
         	
			this.cursor.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
			this.cursor.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
			this.cursor.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
      	}


      	/** Draw marker **/
      	private function drawUp():void 
		{
         	graphics.lineStyle(1, 0xFF0000);
         	graphics.beginFill(0xFFFFFF, 1);
         	graphics.drawRect(-3, -3, 6, 6);
         	graphics.endFill();
         	graphics.lineStyle();
      	}


      private function drawOver(): void {
         graphics.lineStyle(1, 0xFF0000)
         graphics.beginFill(0xFF0000, 1)
         graphics.drawRect(-3, -3, 6, 6)
         graphics.endFill()
         graphics.lineStyle()
      }


      private function onMouseOver (event:MouseEvent): void {
         if (isDrag) return
         Mouse.hide()
         addChild(cursor)
         cursor.visible = true
         graphics.clear()
         drawOver()
      }


      private function onMouseOut (event:MouseEvent): void {
         if (isDrag) return

         if (getChildByName("cursor"))
            removeChild(cursor)
         Mouse.show()
         cursor.visible = false

         graphics.clear()
         drawUp()
      }


      /** Mouse event handler **/      
      private function onMouseUp (event:MouseEvent): void {
         trace("MarkerMouseUp")
         dispatchEvent(new ScaleBoundEvent(ScaleBoundEvent.DESELECT))
         stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove)
         stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp)
         Mouse.show()
         if (getChildByName("cursor"))
            removeChild(cursor)
         cursor.visible = false
         graphics.clear()
         drawUp()
         isDrag = false
      }


      /** Mouse event handler **/
      private function onMouseDown (event:MouseEvent): void {
         dispatchEvent(new ScaleBoundEvent(ScaleBoundEvent.SELECT))
         stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove)
         stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp)
         if (dblclick)
            dispatchEvent(new ScaleBoundEvent(ScaleBoundEvent.DBLCLICK, 0, 0, false, true))
         dblclick = true
         clearInterval(dblclickInter)
         dblclickInter = setInterval(onDoubleClick, _DBLCLICK_INTER)
      }


      /**  **/
      private function onDoubleClick (): void {
         clearInterval(dblclickInter)
         dblclick = false
      }


      /** Mouse event handler **/
      private function onMouseMove (event:MouseEvent): void {
         isDrag = true
         saveProportins = event.shiftKey
         if (getTimer() - lastUpdateTime > _UPDATE_POSITION_INTER) {
            lastUpdateTime = getTimer()
            moveUnderCursor(new Point(event.stageX, event.stageY))
         }
      }


      /** Move marker under cursor **/
      private function moveUnderCursor (coor:Point): void {
         var oldX: Number = x
         var oldY: Number = y
         var pcoor: Point = parent.globalToLocal(coor)

         x = horizontalDrag ? pcoor.x : x
         y = verticalDrag ? pcoor.y : y

         if (saveProportins && !horizontalDrag)
            throw ("Error: You can't save position of marker and disable move in one direction.")

         var dx: Number = pcoor.x - oldX
         var dy: Number = saveProportins ? dx : pcoor.y - oldY

         dispatchEvent(new ScaleBoundEvent(ScaleBoundEvent.CHANGE, dx, dy, saveProportins))
      }


   }
}